using System;
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
/**
 * @author DenseFog
 * @Date: 11/28/2016.
 * onEnter>onSelected>onDown>onUp>onClick>onExit>onUpdateSelected  //传说...
 * 基本包含了UI事件监听注册,实现了长按等 使用方法 
 * UIEventTrigger.Get (_uiCompentBehivour.buttons [1]).onClick = OnClickLeftCallBack; 
 * private void OnClickLeftCallBack(GameObject obj);
 */
//UnityEngine.EventSystems.EventTrigger
namespace Adventure
{
	public class UIEventTrigger : EventTrigger
	{

		public const int EventClick = (1 << 0);
		public const int EventBeginDrag = (1 << 1);
		public const int EventDragging = (1 << 2);
		public const int EventEndDrag = (1 << 3);
		public const int EventDown = (1 << 4);
		public const int EventUp = (1 << 5);

		private float _longClickTime = 1.0f;
		private Selectable _selectable;
		private bool _alreadyUseLongClick = false;
		private bool _alreadyDrag = false;
		private float _clickIntervalTime = 0.2f;
		private bool _isDoubleClick = false;
		public void SetSelectable(Selectable selectable)
		{
			this._selectable = selectable;
		}

		public const int AllEvents = EventClick |
									  EventBeginDrag |
									  EventDragging |
									  EventEndDrag |
									  EventDown |
									  EventUp;

		private int _enabledEvents = AllEvents;
		public delegate void VoidDelegate(GameObject go);
		public delegate void TwoParamDelegate(GameObject go, PointerEventData data);
		public VoidDelegate onClick;
		public VoidDelegate onLongClick;
		public VoidDelegate onLongCancel;
		public VoidDelegate onDown;
		public VoidDelegate onEnter;
		public VoidDelegate onExit;
		public VoidDelegate onUp;
		public VoidDelegate onSelect;
		public VoidDelegate onUpdateSelect;
		public VoidDelegate onDeselect;
		public VoidDelegate onDoubleClick;
		public TwoParamDelegate onDrag;
		public TwoParamDelegate onBeginDrag;
		public TwoParamDelegate onEndDrag;
		public TwoParamDelegate onScroll;
		public VoidDelegate onTips;
		// public string onClickSound = GameConstant.SOUND_UI_CLICK;


		public Action<bool> onInputSystemDown;

		public static UIEventTrigger Get(UnityEngine.Object obj)
		{
			if (obj == null)
				return null;
			GameObject go = null;
			if (obj is GameObject)
			{
				go = obj as GameObject;
			}
			else if (obj is MonoBehaviour)
			{
				go = (obj as MonoBehaviour).gameObject;
			}
			else
			{
				return null;
			}

			UIEventTrigger listener = go.GetComponent<UIEventTrigger>();
			if (listener == null)
				listener = go.AddComponent<UIEventTrigger>();

			if (obj is UnityEngine.UI.Selectable)
				listener.SetSelectable(obj as Selectable);
			return listener;
		}

		private bool isCheckInteractable()
		{
			return _selectable != null && _selectable.interactable == false;
		}

		public void SetEnabledEvents(int events)
		{
			_enabledEvents = events;
		}

		public override void OnPointerClick(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;

			if ((_enabledEvents & EventClick) == 0)
				return;

			if (onDoubleClick == null)
			{
				if (onClick != null && !_alreadyUseLongClick)
				{
					//  Game.SoundManager.PlaySound(onClickSound);
					onClick(gameObject);
				}
			}
			else
			{
				if (eventData.dragging)
				{
					return;
				}
				if (onClick != null && !_alreadyUseLongClick)
				{
					_isDoubleClick = false;
					//  Game.SoundManager.PlaySound(onClickSound);
					Invoke("OnceClick", _clickIntervalTime);
				}
				if (eventData.clickCount == 2)
				{
					_isDoubleClick = true;
					Invoke("DoubleClick", 0);
				}
			}
		}

		private void OnceClick()
		{
			if (isCheckInteractable())
				return;
			if (onClick != null && !_alreadyUseLongClick && !_isDoubleClick)
			{
				onClick(gameObject);
			}
			else
			{
				return;
			}
		}

		private void DoubleClick()
		{
			if (isCheckInteractable())
				return;
			if (onDoubleClick != null && !_alreadyUseLongClick && _isDoubleClick)
			{
				onDoubleClick(gameObject);
			}
		}

		public override void OnPointerDown(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;

			if ((_enabledEvents & EventDown) == 0)
				return;

			_alreadyUseLongClick = false;
			_alreadyDrag = false;
			if (onDown != null)
				onDown(gameObject);
			if (onLongClick != null)
				Invoke("longClickTrigger", _longClickTime);
			if (onTips != null)
				onTips(gameObject);

			if (onInputSystemDown != null)
				onInputSystemDown(true);
		}

		public void longClickTrigger()
		{
			if (isCheckInteractable())
				return;
			if (onLongClick != null && !_alreadyDrag)
			{
				onLongClick(gameObject);
				_alreadyUseLongClick = true;
			}

		}

		public override void OnPointerEnter(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;
			if (onEnter != null)
				onEnter(gameObject);
		}

		public override void OnPointerUp(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;

			if ((_enabledEvents & EventUp) == 0)
				return;

			if (onUp != null)
				onUp(gameObject);
			if (onLongCancel != null)
				onLongCancel(gameObject);

			if (IsInvoking("longClickTrigger"))
				CancelInvoke("longClickTrigger");



			if (onInputSystemDown != null)
				onInputSystemDown(false);
		}

		public override void OnPointerExit(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;
			if (onExit != null)
				onExit(gameObject);
			if (IsInvoking("longClickTrigger"))
				CancelInvoke("longClickTrigger");

		}

		public override void OnUpdateSelected(UnityEngine.EventSystems.BaseEventData eventData)
		{
			if (isCheckInteractable())
				return;
			if (onUpdateSelect != null)
				onUpdateSelect(gameObject);
		}

		public override void OnSelect(UnityEngine.EventSystems.BaseEventData eventData)
		{
			if (isCheckInteractable())
				return;
			if (onSelect != null)
				onSelect(gameObject);
		}

		public override void OnDeselect(UnityEngine.EventSystems.BaseEventData eventData)
		{
			if (isCheckInteractable())
				return;
			if (onDeselect != null)
				onDeselect(gameObject);
		}

		public override void OnBeginDrag(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;

			if ((_enabledEvents & EventBeginDrag) == 0)
				return;

			_alreadyDrag = true;
			if (onBeginDrag != null)
				onBeginDrag(gameObject, eventData);
		}

		public override void OnDrag(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;

			if ((_enabledEvents & EventDragging) == 0)
				return;

			if (onDrag != null)
				onDrag(gameObject, eventData);
		}
		//
		//	public override void OnDrop (UnityEngine.EventSystems.PointerEventData eventData)
		//	{
		//		base.OnDrop (eventData);
		//	}
		//
		public override void OnEndDrag(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;

			if ((_enabledEvents & EventEndDrag) == 0)
				return;

			if (onEndDrag != null)
				onEndDrag(gameObject, eventData);
		}

		public override void OnScroll(UnityEngine.EventSystems.PointerEventData eventData)
		{
			if (isCheckInteractable())
				return;
			if (onScroll != null)
				onScroll(gameObject, eventData);
		}
		//
		//	public override void OnCancel (UnityEngine.EventSystems.BaseEventData eventData)
		//	{
		//		base.OnCancel (eventData);
		//	}
		//		


		//
		//	public override void OnSubmit (UnityEngine.EventSystems.BaseEventData eventData)
		//	{
		//		base.OnSubmit (eventData);
		//	}
		//
		//	public override void OnScroll (UnityEngine.EventSystems.PointerEventData eventData)
		//	{
		//		base.OnScroll (eventData);
		//	}
		//
		//	public override void OnMove (UnityEngine.EventSystems.AxisEventData eventData)
		//	{
		//		base.OnMove (eventData);
		//	}
		//

	}
}